#include "spi_config.h"
#include "data_parse.h"
#include "Ring_Buf.h"

#include "string.h"
#include <time.h>


#define ONE_FRAME_LEN  1024*10 //单包数据 10K

static vaildMsg_t vaildMsg;

typedef struct msg_recorded
{
    uint16_t frame_id;
    uint16_t frame_offset;

    uint16_t last_frame_id; //
    uint16_t last_frame_offset; //

    uint16_t  resend_times;
    uint32_t  wait_time;
}TS_MSG_RECORDED;

static TS_MSG_RECORDED s_msg_record;

uint32_t  testStartVal;
uint8_t  testCheckVal;
uint32_t tailLocalVal;
static uint32_t count = 0, count_tmp = 0;

#define DATA_FRAME_SIZE   10*1024

uint16_t tail_faile_num = 0, checksum_failed_num = 0;
uint16_t tail_faile_index[10] = {0}, checksum_failed_index = 0;

uint8_t s_DataFrame[DATA_FRAME_SIZE];

//偏移值检查
int id_offset_check(TS_MSG_RECORDED *s_record, uint16_t frame_id, uint16_t frame_offset);
//偏移值设置
int id_offset_set(TS_MSG_RECORDED *s_record, uint16_t frame_id, uint16_t frame_offset);
//获取缓存余量
int free_nums_get(void);

uint8_t frame_parse(RING_BUF_DEF_STRUCT *ring_buf,uint8_t *frameBuf,uint16_t framBufLen, vaildMsg_t *msg)
{
    uint8_t curData = 0,CalcheckSum = 0;
    uint16_t frameLen = 0,i=0;
    headMsg_t *pHeadMsg = NULL;
    dataMsg_t *pDataMsg = NULL;
    uint8_t rxCheckSum = 0;
    uint8_t *pBuf = NULL;
    uint8_t dataTmp[30] = {0};
    const uint8_t headMsgLen = sizeof(headMsg_t);
    const uint8_t dataMsgLen = sizeof(dataMsg_t);

    if(ring_buf == NULL)
        return 0;
    if (RingBuf_Count(ring_buf) < sizeof(dataMsg_t) + 2)   // 2 = checksum + end
        return 0;

    pBuf = dataTmp;
    RingBuf_Peeked_Reset(ring_buf);
    RingBuf_Peek(ring_buf,headMsgLen,pBuf);
    RingBuf_Peeked_Reset(ring_buf);


    /* 1.捕获协议头 */
    if(*pBuf != PROTOCOL_HEAD)
    {
        RingBuf_Read(ring_buf,1,&curData);
        return 0;
    }
    
    /* 2.验证协议头 */
    pHeadMsg = (headMsg_t *)pBuf;
    if(pHeadMsg->checkHead != (uint8_t)(pHeadMsg->head + pHeadMsg->lenMsg.datalen.len1 + pHeadMsg->lenMsg.datalen.len2))
    {
        RingBuf_Read(ring_buf,1,&curData);
        return 0;
    }
    testStartVal = (uint32_t)&ring_buf->buff_addr[0] + ring_buf->read_index;
    testCheckVal = (uint8_t)(pHeadMsg->head + pHeadMsg->lenMsg.datalen.len1 + pHeadMsg->lenMsg.datalen.len2);
    tailLocalVal = testStartVal+pHeadMsg->lenMsg.len+6;

    /* 3.验证数据长度 */
    frameLen = headMsgLen + pHeadMsg->lenMsg.len + 2;  // 2 = checksum + end
    if(RingBuf_Count(ring_buf) < frameLen)
        return 0;
    if((pHeadMsg->lenMsg.len < dataMsgLen - headMsgLen)||frameLen > framBufLen)
    {
        RingBuf_Read(ring_buf,1,&curData);
        return 0;
    }

    /* 4.验证包尾和checksum */ 
    RingBuf_Peek_Pos_Change(ring_buf, frameLen - 2);
    RingBuf_Peek(ring_buf,1,&rxCheckSum);
    RingBuf_Peek(ring_buf,1,&curData);
    RingBuf_Peeked_Reset(ring_buf);
    if(curData != PROTOCOL_TAIL)
    {
        RingBuf_Read(ring_buf,1,&curData);
        
        if(tail_faile_num<10)
        {
            tail_faile_index[tail_faile_num] = count;
        }
        tail_faile_num ++; 
        return 0;
    }
    
    RingBuf_Peek(ring_buf,frameLen,frameBuf);
    RingBuf_Peeked_Reset(ring_buf);
    for(i=0;i<pHeadMsg->lenMsg.len;i++)
    {
        CalcheckSum ^= frameBuf[headMsgLen+i];
    }
    if(rxCheckSum != CalcheckSum)
    {
        RingBuf_Read(ring_buf,1,&curData);
        checksum_failed_num++;
        checksum_failed_index = count + 1;
        return 0;
    }

    //if( (pDataMsg->fragmentFlag & 0x0f) == FRAGMENT_TAIL_PACKAGE)
    //{
    //    tail_faile_num = tail_faile_num;
    //}

    /* 数据校验通过！ */
    pDataMsg = (dataMsg_t *)frameBuf;
    msg->srcAddr = pDataMsg->srcAddr;
    msg->fragmentId = pDataMsg->fragmentId;
    msg->fragmentOffset = pDataMsg->fragmentOffset;
    msg->fragmentFlag = pDataMsg->fragmentFlag;
    msg->dataAddr = (uint8_t *)&frameBuf[dataMsgLen];
    msg->datalen = pHeadMsg->lenMsg.len - dataMsgLen + headMsgLen;
    return 1;
}


void f3f4_protocol_data_serialize_send(vaildMsg_t *msg,uint16_t freeSize)
{
    dataMsg_t *ptxMsg = NULL;
    uint8_t data[200]={0};
    uint8_t i = 0;
    uint16_t checkDataEnd = 0;
    uint8_t checkSum = 0;
    uint8_t checkStart = 0;
    uint16_t txLen = 0;

    ptxMsg = (dataMsg_t *)&data;
    ptxMsg->headMsg.head = PROTOCOL_HEAD;
    ptxMsg->headMsg.lenMsg.len = sizeof(dataMsg_t) - sizeof(headMsg_t) + msg->datalen;
    ptxMsg->headMsg.checkHead = PROTOCOL_HEAD + ptxMsg->headMsg.lenMsg.datalen.len1 + ptxMsg->headMsg.lenMsg.datalen.len2;
    ptxMsg->protocolId = PROTOCOL_ID_FOR_SPI;
    ptxMsg->srcAddr  = msg->srcAddr;
    ptxMsg->destAddr = 0x20;
    ptxMsg->serialNum = 0;
    ptxMsg->version = 0;
    ptxMsg->fragmentFlag = msg->fragmentFlag;
    ptxMsg->reserve = 0;
    ptxMsg->fragmentId = msg->fragmentId;
    ptxMsg->fragmentOffset = msg->fragmentOffset;
    ptxMsg->RxFreeSize = freeSize;
    
    if(msg->datalen > 200 - sizeof(dataMsg_t) - 2)   // 2 = checksum + end
        return;

    memcpy(&data[sizeof(dataMsg_t)],msg->dataAddr,msg->datalen);
    
    checkDataEnd = sizeof(dataMsg_t) + msg->datalen;
    checkStart = sizeof(headMsg_t);
    //checkSum = data[checkIndex];
    for(i=checkStart;i < checkDataEnd;i++)
    {
        checkSum ^= data[i];
    }

    txLen = sizeof(headMsg_t) + ptxMsg->headMsg.lenMsg.len + 2; // 2 = checksum + end
    data[txLen - 2] = checkSum;
    data[txLen - 1] = PROTOCOL_TAIL;

    /* TODO: 使用串口发送data，长度为txLen */
    //debug_usart_send(data,txLen);
}

void dataParse(void)
{
    vaildMsg_t responseMsg;
    uint16_t freeLen = 0;
//    static uint16_t lastFramentId = 0;
//    static uint16_t lastFramentOffset = 0;
    // static uint16_t count = 0, count_tmp = 0;

    uint8_t pack_tail_flg = 0;

    //if(RingBuf_UnusedCount(get_data_buf()) < 10*1024)
    //{
    //    return;
    //}

    if(frame_parse(get_spi_receive_buf(),s_DataFrame,DATA_FRAME_SIZE,&vaildMsg) != 0)
    {
//        if(count % 100  != vaildMsg.fragmentOffset)
//        {
//            printf("count %d, Offset:%d\n", count, vaildMsg.fragmentOffset);
//        }
        
        
        count++;
        RingBuf_Write(get_data_buf(),vaildMsg.dataAddr,vaildMsg.datalen);
        RingBuf_ReadIndex_Change(get_spi_receive_buf(),vaildMsg.datalen+sizeof(dataMsg_t)+2);        
        
        if((vaildMsg.fragmentFlag & 0x0f) == FRAGMENT_START_PACKAGE)
        {
            responseMsg.fragmentId = 0;
            responseMsg.fragmentOffset = 0;
            responseMsg.dataAddr = NULL;
            responseMsg.datalen = 0;
            responseMsg.srcAddr = 0x21;
            responseMsg.fragmentFlag = FLOW_CTRL_RESPONSE;

            freeLen = RingBuf_UnusedCount(get_spi_receive_buf())/ONE_FRAME_LEN;
            if(freeLen > 20)
                freeLen -= 20;
            else
                freeLen = 0;

            f3f4_protocol_data_serialize_send(&responseMsg,freeLen);
            count_tmp = count;
        }

        else if((vaildMsg.fragmentFlag & 0x0f) == FRAGMENT_TAIL_PACKAGE)
        {
            responseMsg.fragmentId = vaildMsg.fragmentId;
            responseMsg.fragmentOffset = vaildMsg.fragmentOffset;
            responseMsg.dataAddr = NULL;
            responseMsg.datalen = 0;
            responseMsg.srcAddr = 0x21;
            responseMsg.fragmentFlag = TOAL_PACKAGE_NOMAL;
            freeLen = RingBuf_UnusedCount(get_spi_receive_buf())/ONE_FRAME_LEN;

            f3f4_protocol_data_serialize_send(&responseMsg,20);
            pack_tail_flg = 1;

        }else 
        {
            /* TODO：分片偏移值校验 */
            
        }
        //printf("Id:%d ,Offset:%d\n", responseMsg.fragmentId, vaildMsg.fragmentOffset);
        // lastFramentId = vaildMsg.fragmentId;
        // lastFramentOffset = vaildMsg.fragmentOffset;

       if((count - count_tmp) % 6 == 0  && (count - count_tmp) > 15 && !pack_tail_flg)
       {
           responseMsg.fragmentId = 0;
           responseMsg.fragmentOffset = 0;
           responseMsg.dataAddr = NULL;
           responseMsg.datalen = 0;
           responseMsg.srcAddr = 0x21;
           responseMsg.fragmentFlag = FLOW_CTRL_RESPONSE;     
//           responseMsg.fragmentFlag = RESEND_RESPONSE;          
           
           //uint32_t FreeLen = RingBuf_UnusedCount(get_spi_receive_buf())>>13;

            //f3f4_protocol_data_serialize_send(&responseMsg,FreeLen > 12 ?  6 + FreeLen - 12 : 6);

            f3f4_protocol_data_serialize_send(&responseMsg, 6);

        }
       pack_tail_flg = 0;
    }
}
uint32_t g_gcode_start_time=0, g_gcode_end_time=0;
void dataConsume(void)
{
    static uint32_t time = 0;
    //static uint32_t count = 0;
    //uint8_t comsumer[10*1024];
    //vaildMsg_t responseMsg;
    //uint16_t freeLen = 0;
    static uint32_t last_count = 0;
    //if(mk_hal_system_get_tick() - time>= 2000)
    {
        //time = mk_hal_system_get_tick();

        //printf("total count:%d, speed:%.2f M/s!",count, (count-last_count)/102.4/2);

        if(g_gcode_end_time)
        {
        //    printf("cost %d seconds !",(g_gcode_end_time-g_gcode_start_time)/1000);
        }
        last_count = count;
        //printf("uart0 run!");
    }

    //if(mk_hal_system_get_tick() - time>= 1)
    {

        //for(int i = 0; i < 2400; i++);

        //count++;

        //time = mk_hal_system_get_tick();

        //RingBuf_Read(get_data_buf(),10*1024,comsumer);

        //if(RingBuf_UnusedCount(get_spi_receive_buf()) < 1024*)

        //if(count % 5 == 0)
        {
            // responseMsg.fragmentId = 0;
            // responseMsg.fragmentOffset = 0;
            // responseMsg.dataAddr = NULL;
            // responseMsg.datalen = 0;
            // responseMsg.srcAddr = 0x21;
            // responseMsg.fragmentFlag = FLOW_CTRL_RESPONSE;

            // freeLen = RingBuf_UnusedCount(get_spi_receive_buf())/ONE_FRAME_LEN;

            // if(freeLen > 5)
            // {
            //     f3f4_protocol_data_serialize_send(&responseMsg,freeLen);
            // }
        }
    }
}

#define READ_DATA_MAX_LEN_ONCE 2048
static uint8_t buf[READ_DATA_MAX_LEN_ONCE];
 
void spi_protocol_run(void)
{

/*    uint32_t remain_size = gcode_get_remain_size(GCODE_STREAM_CHANNEL);
    if(remain_size >= READ_DATA_MAX_LEN_ONCE)
    {
        uint32_t read_size = RingBuf_Read(get_data_buf(), READ_DATA_MAX_LEN_ONCE, buf);
        if(read_size > 0)
        {
            gcode_input(GCODE_STREAM_CHANNEL,buf,read_size);
        }
    } */   

    //dataParse();
    state_machine_run();
    dataConsume();   
}


typedef enum
{
    WAIT_HEAD = 0,
    WAIT_TAIL,
    WAIT_RESEND
}TE_SPI_STATE;

static TE_SPI_STATE s_state = WAIT_HEAD;
static uint8_t s_data[10240];
void ring_data_create(uint16_t id, uint16_t offset, uint16_t flg, uint8_t* data);
void state_machine_run(void)
{

    vaildMsg_t responseMsg;
    uint16_t freeLen = 0;
    uint8_t pack_tail_flg = 0, frame_complete_flg = 0;

    //if(RingBuf_UnusedCount(get_data_buf()) < ONE_FRAME_LEN)
    //{
    //    return;
    //}

    if(frame_parse(get_spi_receive_buf(),s_DataFrame,DATA_FRAME_SIZE,&vaildMsg) != 0)
    {
        frame_complete_flg = 1;
    }

    static int num = 0;
    switch(s_state)
    {
        case WAIT_HEAD: 
            if(frame_complete_flg)
            {
                //frame_complete_flg = 0;
                if((vaildMsg.fragmentFlag & 0x0f) == FRAGMENT_START_PACKAGE) //分片起始
                {

                    RingBuf_Write(get_data_buf(),vaildMsg.dataAddr,vaildMsg.datalen);
                    RingBuf_ReadIndex_Change(get_spi_receive_buf(),vaildMsg.datalen+sizeof(dataMsg_t)+2);

                    responseMsg.fragmentId = 0;
                    responseMsg.fragmentOffset = 0;
                    responseMsg.dataAddr = NULL;
                    responseMsg.datalen = 0;
                    responseMsg.srcAddr = 0x21;
                    responseMsg.fragmentFlag = FLOW_CTRL_RESPONSE;

                    freeLen = RingBuf_UnusedCount(get_spi_receive_buf())/ONE_FRAME_LEN;
                    if(freeLen > 20)
                        freeLen -= 20;
                    else
                        freeLen = 0;

                    f3f4_protocol_data_serialize_send(&responseMsg,freeLen);
                    count_tmp = count;
                    
                    //赋值帧id和分片偏移
                    id_offset_set(&s_msg_record,vaildMsg.fragmentId, vaildMsg.fragmentOffset);
                    s_state = WAIT_TAIL; //切换到等待分片结束状态
                    num = 1;
                    printf("receive packet start, num:%d\n",num);
                }
                else if((vaildMsg.fragmentFlag & 0x0f) == SINGLE_PACKAGE) //单包发送
                {
                    //回复
                    s_state = WAIT_HEAD;
                    
                }
            }
            break;
        case WAIT_TAIL:
            if(frame_complete_flg) //接收到一帧数据
            {
                //frame_complete_flg = 0;
                if(0 == id_offset_check(&s_msg_record, vaildMsg.fragmentId, vaildMsg.fragmentOffset)) //偏移值
                {
                    RingBuf_Write(get_data_buf(),vaildMsg.dataAddr,vaildMsg.datalen);
                    RingBuf_ReadIndex_Change(get_spi_receive_buf(),vaildMsg.datalen+sizeof(dataMsg_t)+2);
                    if((vaildMsg.fragmentFlag & 0x0f) == FRAGMENT_TAIL_PACKAGE) //分片结束
                    {
                        responseMsg.fragmentId = vaildMsg.fragmentId;
                        responseMsg.fragmentOffset = vaildMsg.fragmentOffset;
                        responseMsg.dataAddr = NULL;
                        responseMsg.datalen = 0;
                        responseMsg.srcAddr = 0x21;
                        responseMsg.fragmentFlag = TOAL_PACKAGE_NOMAL;
                        freeLen = RingBuf_UnusedCount(get_spi_receive_buf())/ONE_FRAME_LEN;

                        f3f4_protocol_data_serialize_send(&responseMsg,20);
                        pack_tail_flg = 1;

                        id_offset_set(&s_msg_record, vaildMsg.fragmentId, vaildMsg.fragmentOffset);
                        s_state = WAIT_HEAD;
                        num++;
                        printf("receive packet tail num:%d\n", num);

                    }
                    else
                    {
                        
                        id_offset_set(&s_msg_record, vaildMsg.fragmentId, vaildMsg.fragmentOffset);
                        s_state = WAIT_TAIL;
                        num++;
                        printf("receive packet num:%d\n",num);
                    }
                }
                else
                {
                    RingBuf_Write(get_data_buf(), vaildMsg.dataAddr, vaildMsg.datalen);
                    RingBuf_ReadIndex_Change(get_spi_receive_buf(), vaildMsg.datalen + sizeof(dataMsg_t) + 2);
                    RingBuf_Up_Lock(get_spi_receive_buf()); //记住该索引

                    s_msg_record.wait_time = 0;
                    s_msg_record.resend_times = 0;
                    s_state = WAIT_RESEND;

                    printf("receive packet error ,offset expect:%d,rec:%d\n", s_msg_record.frame_offset+1, vaildMsg.fragmentOffset);
                    ring_data_create(1, s_msg_record.frame_offset+1, FRAGMENT_INPROCESS_PACKAGE, s_data);
                    RingBuf_Write(get_spi_receive_buf(), s_data, 10240);
                }
            }
            break;

        case WAIT_RESEND:
            ////if(mk_hal_system_get_tick() - s_msg_record.wait_time >= 10) //10ms没有回应
            //{
            //    if(s_msg_record.resend_times <= 10 && free_nums_get() > 0)//重发少于十次，且有剩余空间
            //    {
            //        //发送重发请求
            //        responseMsg.fragmentId = s_msg_record.frame_id; //resend_id;
            //        responseMsg.fragmentOffset = s_msg_record.frame_offset + 1; //resend_offset;
            //        responseMsg.dataAddr = NULL;
            //        responseMsg.datalen = 0;
            //        responseMsg.srcAddr = 0x21;
            //        responseMsg.fragmentFlag = RESEND_RESPONSE;
            //        f3f4_protocol_data_serialize_send(&responseMsg, 1); //要求重发，请求一包数据

            //        s_msg_record.resend_times++;
            //    }
            //    else if(free_nums_get() <= 0) //没有剩余空间
            //    {
            //        RingBuf_Flush(get_spi_receive_buf()); //清除缓存
            //    }
            //    else
            //    {
            //        RingBuf_Free_Lock(get_spi_receive_buf());
            //        s_msg_record.resend_times = 0;
            //        //上报通信异常
            //    }
            //}
            if(frame_complete_flg) //接收到一帧数据
            {
                //frame_complete_flg = 0;
                if(0 == id_offset_check(&s_msg_record, vaildMsg.fragmentId, vaildMsg.fragmentOffset)) //偏移值
                {
                    RingBuf_Write(get_data_buf(),vaildMsg.dataAddr,vaildMsg.datalen);
                    RingBuf_ReadIndex_Change(get_spi_receive_buf(),vaildMsg.datalen+sizeof(dataMsg_t)+2);                    
                    if((vaildMsg.fragmentFlag & 0x0f) == FRAGMENT_TAIL_PACKAGE) //分片结束
                    {
                        responseMsg.fragmentId = vaildMsg.fragmentId;
                        responseMsg.fragmentOffset = vaildMsg.fragmentOffset;
                        responseMsg.dataAddr = NULL;
                        responseMsg.datalen = 0;
                        responseMsg.srcAddr = 0x21;
                        responseMsg.fragmentFlag = TOAL_PACKAGE_NOMAL;
                        freeLen = RingBuf_UnusedCount(get_spi_receive_buf())/ONE_FRAME_LEN;

                        f3f4_protocol_data_serialize_send(&responseMsg,20);
                        pack_tail_flg = 1;
                        id_offset_set(&s_msg_record, vaildMsg.fragmentId, vaildMsg.fragmentOffset);
                        s_state = WAIT_HEAD;
                        printf("receive packet tail:%d\n", num);
                    }
                    else
                    {        
                        num++;
                        printf("receive resend packet num:%d\n", num);
                        id_offset_set(&s_msg_record, vaildMsg.fragmentId, vaildMsg.fragmentOffset);                
                        s_state = WAIT_TAIL;
                    }

                    RingBuf_Free_Lock(get_spi_receive_buf());
                }
                else
                {
                    RingBuf_Write(get_data_buf(), vaildMsg.dataAddr, vaildMsg.datalen);
                    RingBuf_ReadIndex_Change(get_spi_receive_buf(), vaildMsg.datalen + sizeof(dataMsg_t) + 2);
                }
            }
            break;

        default:
            break;  
    }

    if(frame_complete_flg)
    {
        frame_complete_flg = 0;
        count++;


        if((count - count_tmp) % 6 == 0  && (count - count_tmp) > 15 && !pack_tail_flg)
        {
            responseMsg.fragmentId = 0;
            responseMsg.fragmentOffset = 0;
            responseMsg.dataAddr = NULL;
            responseMsg.datalen = 0;
            responseMsg.srcAddr = 0x21;
            responseMsg.fragmentFlag = FLOW_CTRL_RESPONSE;     
        //           responseMsg.fragmentFlag = RESEND_RESPONSE;          
            
            //uint32_t FreeLen = RingBuf_UnusedCount(get_spi_receive_buf())>>13;

            //f3f4_protocol_data_serialize_send(&responseMsg,FreeLen > 12 ?  6 + FreeLen - 12 : 6);

            f3f4_protocol_data_serialize_send(&responseMsg, 6);

        }
        pack_tail_flg = 0;
    }
}


//偏移值检测
int id_offset_check(TS_MSG_RECORDED *s_record, uint16_t frame_id, uint16_t frame_offset)
{
    if((s_record->frame_id == frame_id && s_record->frame_offset+1 == frame_offset))
    {
        s_record->frame_id = frame_id;
        s_record->frame_offset = frame_offset;
        return 0;
    }
    return -1;
}

//偏移值设置
int id_offset_set(TS_MSG_RECORDED *s_record, uint16_t frame_id, uint16_t frame_offset)
{
    s_record->frame_id = frame_id;
    s_record->frame_offset = frame_offset;
    return 0;
}

//获取缓存余量
int free_nums_get(void)
{
    int free_len = RingBuf_UnusedCount(get_spi_receive_buf())/ONE_FRAME_LEN;
    return free_len;
}


//create frame
void f3f4_protocol_frame_create(vaildMsg_t* msg, uint8_t *data)
{
    dataMsg_t* ptxMsg = NULL;
    //uint8_t data[10240] = { 0 };
    uint16_t i = 0;
    uint16_t checkDataEnd = 0;
    uint8_t checkSum = 0;
    uint8_t checkStart = 0;
    uint16_t txLen = 0;

    ptxMsg = (dataMsg_t*)data;
    ptxMsg->headMsg.head = PROTOCOL_HEAD;
    ptxMsg->headMsg.lenMsg.len = sizeof(dataMsg_t) - sizeof(headMsg_t) + msg->datalen;
    ptxMsg->headMsg.checkHead = PROTOCOL_HEAD + ptxMsg->headMsg.lenMsg.datalen.len1 + ptxMsg->headMsg.lenMsg.datalen.len2;
    ptxMsg->protocolId = PROTOCOL_ID_FOR_SPI;
    ptxMsg->srcAddr = msg->srcAddr;
    ptxMsg->destAddr = 0x20;
    ptxMsg->serialNum = 0;
    ptxMsg->version = 0;
    ptxMsg->fragmentFlag = msg->fragmentFlag;
    ptxMsg->reserve = 0;
    ptxMsg->fragmentId = msg->fragmentId;
    ptxMsg->fragmentOffset = msg->fragmentOffset;
    ptxMsg->RxFreeSize = 0;

    if (msg->datalen > 10240 - sizeof(dataMsg_t) - 2)   // 2 = checksum + end
        return;

    memcpy((void *)&data[sizeof(dataMsg_t)], msg->dataAddr, msg->datalen);

    checkDataEnd = sizeof(dataMsg_t) + msg->datalen;
    checkStart = sizeof(headMsg_t);
    //checkSum = data[checkIndex];
    for (i = checkStart; i < checkDataEnd; i++)
    {
        checkSum ^= data[i];
    }
    static uint8_t flg = 0;
    if (msg->fragmentOffset == 5 && !flg)
    {
        flg = 1;
        checkSum = 0x0;
    }
    txLen = sizeof(headMsg_t) + ptxMsg->headMsg.lenMsg.len + 2; // 2 = checksum + end
    data[txLen - 2] = checkSum;
    data[txLen - 1] = PROTOCOL_TAIL;

    /* TODO: 使用串口发送data，长度为txLen */
    //debug_usart_send(data,txLen);
}
